package com.cy.pj.common.config;

import java.util.LinkedHashMap;

import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;


@Configuration
public class SpringShiroConfig {
	/***
	 * SecurityManager 对象为Shiro的核心板
	 * @Bean 通常会配置@Configuration注解进行使用
	 * 1)自助借描述方法会交给spring管理
	 * 2)@Bean注解没有指定其value属性的值,Bean的名字默认为反复噶名
	 * @return
	 */
	//@Bean(value="SManager")
	@Bean
	public SecurityManager securityManager(Realm realm) {
		DefaultWebSecurityManager sManager=new DefaultWebSecurityManager();
		sManager.setRealm(realm);
		return sManager;
	}
	/***
	 * Spring容器在管理 ShiroFilterFactoryBean 对象,会基于这个对象创建过滤器工厂对象(SpringShiroFilter),
	 * 然后通过过滤器工厂创建过滤器(Filter)对象,通过Filter对请求数据进行过滤
	 * 例如通过securityManager的方法判断此请求是否已经给认证,假如没有认证则跳转到登录页面
	 * @param securityManager
	 * @return
	 */
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactory (SecurityManager securityManager) {
		ShiroFilterFactoryBean sfBean=new ShiroFilterFactoryBean();
		//定义map指定请求过滤规则(哪些资源允许匿名访问,哪些必须认证访问)
		sfBean.setSecurityManager(securityManager);
		//设置认证不通过时要跳转的页面(登录页面)
		sfBean.setLoginUrl("/doLoginUI");
		LinkedHashMap<String,String> map= new LinkedHashMap<>();
		
		/** 静态资源允许匿名访问:"anon" */
		map.put("/bower_components/**","anon");//anne为Shiro框架定义会对应一个过滤器对象
		map.put("/build/**","anon");
		map.put("/dist/**","anon");
		map.put("/plugins/**","anon");
		map.put("/user/doLogin", "anon"); //登录操作允许匿名访问
		map.put("/doLogout", "logout");//logout为登出操作,此操作执行时会进入登录页面
	//	map.put("/doIndexUI", "anon"); //首页页面
		
		/** 除了匿名访问的资源,其它都要认证("authc")后访问 */
		map.put("/**","authc"); 
		sfBean.setFilterChainDefinitionMap(map);
		return sfBean;
	}
	/***
	 * 配置Advisor对象 此对象会关联切入点和通知
	 * @param securityManager
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor (SecurityManager securityManager) {
		//顾问对象
		AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
		advisor.setSecurityManager(securityManager);
		return advisor;
	}


}
